پرش به مطلب اصلی

Rate limiter

اول از همه: Rate Limiter یعنی چی؟

Rate limiter یه مکانیزمه که جلوی سیل درخواست‌ها رو می‌گیره. مثلاً اگه یه API داری که فقط می‌خوای کاربر ۱۰۰ بار در دقیقه بهش درخواست بده، rate limiter کاری می‌کنه که درخواست‌های اضافه رو بندازه دور یا نگه‌داره.
این کار معمولاً با الگوریتم‌های مختلفی انجام می‌شه که هرکدوم مزایا و معایب خودشون رو دارن.


1. Token Bucket

فرض کن یه سطل داری که توش توکن میریزی. هر توکن یعنی مجوز یه درخواست.
سطل یه ظرفیت مشخص داره (مثلاً 10 تا توکن) و با یه نرخ ثابت پر می‌شه (مثلاً ۵ تا در ثانیه).

هر وقت یه request میاد، اگه توکن توی سطل باشه، یکی ازش برمی‌داره و request رو قبول می‌کنه.
اگه سطل خالی باشه، request رد می‌شه.

مزیت‌ها:

  • تا وقتی توکن هست، درخواست‌ها می‌تونن با سرعت زیاد بیان (burst مجاز).

  • حافظه کمی می‌خواد چون فقط باید تعداد توکن‌ها رو نگه داره.

عیب‌ها:

  • برای sync کردن بین threadها یا processها معمولاً lock نیاز داری، که ممکنه delay بده.

  • پیدا کردن بهترین مقدار ظرفیت و refill rate سخته.


2. Leaking Bucket

اینجا به جای توکن، خود درخواست‌ها توی سطل جمع می‌شن و با یه نرخ ثابت ازش خارج می‌شن.
مثل یه سطل آب که با یه سوراخ کوچیک آبش چکه می‌کنه. درخواست‌ها FIFO (اول اومده اول می‌ره) پردازش می‌شن.

مزیت‌ها:

  • چون خروجی با نرخ ثابته، دیگه burst نداری.

  • حافظه کمی نیاز داره.

  • برای سیستم‌هایی که نرخ خروجی ثابتی دارن خیلی خوبه (مثلاً queueهای ثابت).

عیب‌ها:

  • اگه ناگهان درخواست زیاد بیاد، سطل پر می‌شه و بقیه requestها drop می‌شن.

  • تعیین اندازه‌ی مناسب سطل و نرخ خروج سخت‌تره.


3. Fixed Window Counter

اینجا زمانو به بازه‌های مساوی تقسیم می‌کنی، مثلاً هر دقیقه.
برای هر بازه یه counter داری که تعداد درخواست‌ها رو می‌شمره.
اگه از حد مجاز گذشت، بقیه requestها رد می‌شن تا بازه‌ی بعدی شروع شه.

مشکل بزرگش:
در لبه‌های زمانی ممکنه burst بزنه. مثلاً اگه limit ده‌تا در دقیقه باشه، کاربر ممکنه ۱۰ تا request آخر دقیقه بزنه و ۱۰ تای اول دقیقه‌ی بعد → یعنی ۲۰ تا در یه دقیقه واقعی.

مزیت‌ها:

  • ساده و کم‌حافظه.
    عیب‌ها:

  • اون حالت burst در مرزهای زمانی باعث افت performance می‌شه.


4. Sliding Window Log

اینجا برای هر request، زمان ورودش رو ذخیره می‌کنی (توی یه log یا hashmap).
هر بار که یه request جدید میاد، log رو چک می‌کنی ببینی توی بازه‌ی زمانی مثلاً یک دقیقه گذشته چند تا درخواست بوده.
اگه کمتر از limit بود، request رو قبول می‌کنی، وگرنه ردش می‌کنی.

مزیت‌ها:

  • مشکل مرز زمانی (edge case) نداره چون sliding هست.
    عیب‌ها:

  • حافظه بیشتری می‌خواد چون باید زمان تمام requestها رو ذخیره کنی.


5. Sliding Window Counter

این یکی یه ترکیب هوشمند از fixed window و sliding log هست.
در واقع یه میانگین بین تعداد requestهای پنجره قبلی و فعلی حساب می‌کنه تا نرخ نرمی به‌دست بیاد.

مثلاً اگه limit صدتا در دقیقه باشه، و در پنجره قبلی ۸۸ تا و الان ۱۲ تا بوده، با فرمول overlap، یه نرخ حدود ۷۸ حساب می‌کنه → چون کمتر از ۱۰۰ه، request قبول می‌شه.

مزیت‌ها:

  • حافظه کمی لازم داره چون فقط باید شمارنده‌ی پنجره فعلی و قبلی و درصد overlap رو نگه داره.

  • نرخ ترافیک رو نرم و یکنواخت می‌کنه (no sudden spikes).

عیب‌ها:

  • فرض می‌کنه درخواست‌های پنجره قبلی یکنواخت بودن، که همیشه درست نیست.